#include "N1Debug.h"
#include "N1StaticVariable.h"

bool N1LeakTest::m_started;
N1StaticVariable<N1List> m_data;


class N1AllocatedData : public N1Object {
protected:
    void*    m_handle;
    N1UInt32 m_size;
    friend class N1LeakTest;
public:
    N1NAME(N1AllocatedData)
    N1DESC

    N1AllocatedData(void* handle, N1UInt32 size)
      : m_handle(handle), m_size(size) 
    { 
    }

    ~N1AllocatedData() {}

    virtual bool isEqualTo(N1Object *obj) {
        N1AllocatedData *data = dynamic_cast<N1AllocatedData*>(obj);
        if(data->m_handle==m_handle)
            return true;
        return false;
    }
};

void N1LeakTest::start()
{
    m_started = true;
}

void N1LeakTest::stop()
{
    m_started = false;
}

void N1LeakTest::alloc(void* handle, N1UInt32 size)
{
    if(m_started)
    {
        m_data->addHead(new N1AllocatedData(handle, size));
    }
}

void N1LeakTest::free(void* handle)
{
    N1POSITION pos = m_data->getHeadPosition( );
    N1POSITION lastPos;
    while(pos) 
    {
        lastPos = pos;
        N1Object *obj = m_data->getNext(pos);
        N1AllocatedData* data = dynamic_cast<N1AllocatedData*>(obj);
        if(data)
        {
            if(data->m_handle == handle)
            {
                m_data->removeAt(lastPos);
                return;
            }
        }
    }
}

void N1LeakTest::clear()
{
    m_data->removeAll();
}

void N1LeakTest::print()
{
}


void* operator new( size_t stAllocateBlock ) {
    void*  mem = malloc( stAllocateBlock );
    return mem;
}

void operator delete( void *pvMem ) {
    free( pvMem );
}

